package MapaStuff;

import java.util.Observable;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import Construibles.Construible;
import Construibles.ZonaNula;
import Desastres.Godzilla;
import Excepciones.FueraDeLimites;
import Excepciones.SuperficieNoValida;
import Ubicacion.Punto;

public class Hectarea extends Observable{
	
	protected Punto punto;
	protected Construible contenido;
	protected Superficie superficie;
	private boolean godzilla;
	
	public Hectarea(Punto punto,Superficie unSuperficie) {
		this.punto = punto;
		this.superficie=unSuperficie;
		this.contenido=new ZonaNula();
		godzilla = false;
		
	}

	public Punto punto(){
		return punto;
	}
	
	public int distancia(Hectarea hectarea){
		return this.punto.distancia(hectarea.punto);
	}
	
	public void construir(Construible unConstruible) throws SuperficieNoValida{
		if (superficie.puedeConstruir(unConstruible)){
			contenido=unConstruible;
			unConstruible.agregarHectarea(this);
			setChanged();
			this.notifyObservers();
		}
		else {
			throw new SuperficieNoValida(null);
		}
		
	}
	
	public Construible contenido () {
		return this.contenido;
	}
	
	public Superficie tipoDeSuperficie(){
		return (superficie);
	}
	
	public void sanar() {
		contenido.sanar();
		setChanged();
		this.notifyObservers();
		
	}

	public void daniarConstruccion(Godzilla godzilla) {
	this.contenido.daniadoPorGodzilla();
	}

	public Hectarea este() throws FueraDeLimites {
		Hectarea hectareaDelEste = Mapa.darMapa().darHectarea(punto.este());
		return hectareaDelEste;
	}

	public Hectarea oeste() throws FueraDeLimites {
		Hectarea hectareaDelOeste = Mapa.darMapa().darHectarea(punto.oeste());
		return hectareaDelOeste;
	}

	public Hectarea norte() throws FueraDeLimites {
		Hectarea hectareaDelNorte = Mapa.darMapa().darHectarea(punto.norte());
		return hectareaDelNorte;
	}
	
	public Hectarea sur() throws FueraDeLimites {
		Hectarea hectareaDelSur = Mapa.darMapa().darHectarea(punto.sur());
		return hectareaDelSur;
	}

	public Hectarea noreste() throws FueraDeLimites {
		Hectarea hectareaDelNoreste = Mapa.darMapa().darHectarea(punto.noreste());
		return hectareaDelNoreste;
	}
	
	public Hectarea noroeste() throws FueraDeLimites {
		Hectarea hectareaDelNoroeste = Mapa.darMapa().darHectarea(punto.noroeste());
		return hectareaDelNoroeste;
	}
	
	public Hectarea sureste() throws FueraDeLimites {
		Hectarea hectareaDelSureste = Mapa.darMapa().darHectarea(punto.sureste());
		return hectareaDelSureste;
	}
	
	public Hectarea suroeste() throws FueraDeLimites {
		Hectarea hectareaDelSuroeste = Mapa.darMapa().darHectarea(punto.suroeste());
		return hectareaDelSuroeste;
	}

	public boolean estaEnElLimite() {
		return ( (this.punto().getX() == 1) || 
				 (this.punto().getY() == 1) || 
				 (this.punto().getX() == Mapa.darMapa().ancho() ) ||
				 (this.punto().getY() == Mapa.darMapa().alto()) ) ;
	}

	public int valorSuperficie() {
		
		return superficie.valorSuperficie();
	}

	public void tieneGodzilla() {
		godzilla = true;
		setChanged();
		this.notifyObservers();
	}
	
	public void godzillaSeFue(){
		godzilla = false;
		setChanged();
		this.notifyObservers();
	}

	public String nombre() {
		if (godzilla){
			return "GOD";
		}
		else return contenido.nombre();
	}

	public void daniarConstruccion(int i) {
		contenido.daniar(i);
		setChanged();
		notifyObservers();
		
	}
	
	public Element serializar(Document doc){
		Element eleHectarea=doc.createElement("Hectarea");
		eleHectarea.appendChild(punto.serializar(doc));
		eleHectarea.appendChild(contenido.serializar(doc));
		eleHectarea.appendChild(superficie.serializar(doc));
		eleHectarea.setAttribute("godzila",Boolean.toString(godzilla));
		return eleHectarea;
	}

	public static Hectarea hidratar(Node node)  {
		Element eleHectarea=(Element) node;
		Punto punto=Punto.hidratar(eleHectarea.getChildNodes().item(0));
		Construible contenido=Construible.hidratar(eleHectarea.getChildNodes().item(1));
		Superficie superficie=Superficie.hidratar(eleHectarea.getChildNodes().item(2));
		boolean godzilla=Boolean.parseBoolean( eleHectarea.getAttribute("godzila"));
		Hectarea hectarea=new Hectarea(punto,superficie);
		hectarea.godzilla=godzilla;;
		try{
			hectarea.construir(contenido);
		}catch(SuperficieNoValida e){};
		return hectarea;
	}
	
}
